package com.my.java8;

import java.util.function.Function;
import java.util.function.UnaryOperator;

public class ChainExample {

	public static abstract class ProcessingObject<T> {
		protected ProcessingObject<T> successor;

		public void setSuccessor(ProcessingObject<T> successor) {
			this.successor = successor;
		}

		public T handle(T input) {
			T r = handleWork(input);
			if (successor != null) {
				return successor.handle(r);
			}
			return r;
		}

		abstract protected T handleWork(T input);

	}
	
	public static class HeaderTextProcessing extends ProcessingObject<String>{

		@Override
		protected String handleWork(String input) {
			
			return "From header...."+input;
		}
		
	}
	
	public static class SpellCheckerProcessing extends ProcessingObject<String>{

		@Override
		protected String handleWork(String input) {
			
			return input.replaceAll("header", "Header");
		}
		
	}
	
	public static void main(String[] args) {
		ProcessingObject<String> p1 = new HeaderTextProcessing();
		ProcessingObject<String> p2 = new SpellCheckerProcessing();

		p1.setSuccessor(p2);
		System.out.println(p1.handle("yeah...yeah..."));
		
		UnaryOperator<String> headerProcesing = text->"From header..."+text;
		UnaryOperator<String> spellProcesing = text->text.replaceAll("header", "Header");
		
		Function<String, String> pipeline = headerProcesing.andThen(spellProcesing);
		System.out.println(pipeline.apply("hahaha"));
		
	}

}
